package executor

import (
	"github.com/kataras/golog"
	"sdn-executor/model/common"
	"sdn-executor/utils/erros"
	"time"
)

type SdnExecutorResult struct {
	ID          int64     `json:"id" gorm:"primaryKey"`
	Device      string    `json:"device"`
	Status      string    `json:"status"`
	Sequence    int       `json:"sequence"`
	RequestId   string    `json:"requestId"`
	RequestType string    `json:"requestType"`
	Channel     uint      `json:"channel"`
	Priority    int       `json:"priority"`
	User        string    `json:"user"`
	Caller      string    `json:"caller"`
	ReadOnly    bool      `json:"readOnly"`
	Reason      string    `json:"reason"`
	Request     string    `json:"request"`
	Result      string    `json:"result"`
	CreateTime  time.Time `json:"createTime" gorm:"autoCreateTime"`
	UpdateTime  time.Time `json:"updateTime" gorm:"autoUpdateTime"`
}

func (SdnExecutorResult) TableName() string {
	return "sdn_executor_result"
}

func QuerySdnExecutorResultByRequestId(requestId string) ([]*SdnExecutorResult, *erros.Error) {
	var results []*SdnExecutorResult
	tx := ExeDB.Where("`request_id` = ?", requestId).Order("`sequence` asc").Find(&results)
	if tx.Error != nil {
		// 处理错误
		golog.Errorf("QuerySdnExecutorResultByRequestId failed. requestId: %s, err: %+v", requestId, tx.Error)
		return nil, erros.New(erros.CodeAbnormalDependencyService, "%v", tx.Error)
	}
	return results, nil
}

func CreateSdnExecutorResult(result *SdnExecutorResult) *erros.Error {
	tx := ExeDB.Create(result)
	if tx.Error != nil {
		golog.Errorf("create SdnExecutorResult failed. device: %s, requestId: %s, order: %d, err: %+v", result.Device, result.RequestId, result.Sequence, tx.Error)
		return erros.New(erros.CodeAbnormalDependencyService, "%v", tx.Error)
	}
	return nil
}

func UpdateSdnExecutorResult(result *SdnExecutorResult, fields ...string) *erros.Error {
	tx := ExeDB.Model(result).Select(fields).Updates(result)
	if tx.Error != nil {
		golog.Errorf("update SdnExecutorResult failed. device: %s, requestId: %s, order: %d, err: %+v", result.Device, result.RequestId, result.Sequence, tx.Error)
		return erros.New(erros.CodeAbnormalDependencyService, "%v", tx.Error)
	}
	return nil
}

func UpdateSdnExecutorResultStatusByRequestIdAndOrder(requestId string, order int, status string) *erros.Error {
	tx := ExeDB.Model(&SdnExecutorResult{}).
		Where("request_id = ? and sequence = ?", requestId, order).
		Update("status", status)
	if tx.Error != nil {
		golog.Errorf("UpdateSdnExecutorResultStatusByRequestIdAndOrder failed. requestId: %s, order: %d, status: %s, err: %+v",
			requestId, order, status, tx.Error)
		return erros.New(erros.CodeAbnormalDependencyService, "%v", tx.Error)
	}
	return nil
}

func SuccessSdnExecutorResult(requestId string, order int, result string) *erros.Error {
	tx := ExeDB.Model(&SdnExecutorResult{}).
		Where("request_id = ? and sequence = ?", requestId, order).
		Updates(map[string]any{"result": result, "status": string(common.ExecStatusSuccess)})
	if tx.Error != nil {
		golog.Errorf("SuccessSdnExecutorResult failed. requestId: %s, order: %d, err: %+v", requestId, order, tx.Error)
		return erros.New(erros.CodeAbnormalDependencyService, "%v", tx.Error)
	}
	return nil
}

func FailSdnExecutorResult(requestId string, order int, result string, reason string) *erros.Error {
	tx := ExeDB.Model(&SdnExecutorResult{}).
		Where("request_id = ? and sequence = ?", requestId, order).
		Updates(map[string]any{"result": result, "reason": reason, "status": string(common.ExecStatusFail)})
	if tx.Error != nil {
		golog.Errorf("FailSdnExecutorResult failed. requestId: %s, order: %d, reason: %s, err: %+v",
			requestId, order, reason, tx.Error)
		return erros.New(erros.CodeAbnormalDependencyService, "%v", tx.Error)
	}
	return nil
}
